//发送消息的类



import {
	getGridCode
} from '../utils/getSurroundingGrids';
import store from "../store";


export default class MessageSender {
	/**
	 * 初始化消息发送器
	 * @param {Object} storeData - 全局状态数据（包含 user、location、ws 等）
	 * @param {Object} storeData.user - 当前用户信息
	 * @param {Object} storeData.location - 当前地理位置
	 * @param {Object} storeData.senderLocation - 发送者位置（可选）
	 * @param {Object} storeData.ws - WebSocket 实例
	 * @param {Object} storeData.stateConfig - 音效/振动配置
	
	 */
	constructor(storeData) {
		// 初始化核心依赖（从 storeData 提取，避免重复传递）
		this.user = storeData.user;
		this.location = storeData.location;
		this.senderLocation = storeData.senderLocation;
		this.ws = storeData.ws;
		this.stateConfig = storeData.stateConfig;

		// 校验必要参数（初始化时提前报错，避免后续发送失败）
		if (!this.user?.userId || !this.ws) {
			throw new Error("MessageSender初始化失败：缺少 user.userId 或 WebSocket 实例");
		}
	}


	/** @param {Object} toTarget - 消息接收目标（{ targetType, targetId }）
	    @throws {Error} 当 targetType 为 1/2 但无 targetId 时抛出错误 
	 */
	#validateToTarget(toTarget) {
		// 1. 基础校验：toTarget 必须是对象
		if (!toTarget || typeof toTarget !== 'object') {
			throw new Error('接收目标 toTarget 必须是对象');
		}

		// 2. 提取 targetType 并转为数字（避免字符串类型导致判断错误）
		const {
			targetType,
			targetId
		} = toTarget;
		const type = Number(targetType);

		// 3. 核心校验：targetType 为 1 或 2 时，必须有 targetId
		if ([2, 3].includes(type)) {
			// 校验 targetId 存在且不为空（根据业务需求调整，如允许数字/字符串类型）
			if (targetId === undefined || targetId === null || targetId === '') {
				throw new Error(`targetType 为 ${type} 时，targetId 不能为空`);
			}
		}

		// 4. 可选：校验 targetType 必须是合法值（如仅允许 1/2/3...）
		const validTypes = [1, 2, 3]; // 根据实际业务补充合法类型
		if (!validTypes.includes(type)) {
			throw new Error(`MessageSender:targetType 必须是 ${validTypes.join('/')}，当前为 ${targetType}`);
		}
	}
	/**
	 * 私有方法：构建基础消息对象（修改后）
	 * @param {number} msgType - 消息类型
	 * @param {Object} toTarget - 消息接收目标
	 * @param {Object} content - 消息内容
	 * @returns {Object} 完整消息对象
	 */
	#buildBaseMessage(msgType, toTarget, content) {
		// 先校验 toTarget 合法性，不通过则直接报错
		this.#validateToTarget(toTarget);


		// 后续构建消息的逻辑不变...
		return {
			sendUserId: this.user.userId,
			userTel: this.user.userTel,
			nicPic: this.user.nicPic,
			nicName: this.user.nicName,
			content: {
				text: "",
				voicePath: "",
				duration: 0,
				productId: "",
				sendshopId: "",
				mediaPath: "",
				senderLocation: this.senderLocation,
				...content
			},
			location: this.location,
			toTarget: toTarget, // 校验通过后再使用
			messageType: msgType,
			timestamp: Date.now(),
			receiveDistance: 500,
			webSocketType: "msg",
			isRead: false,
			grid: getGridCode(this.location)
		};
	}




	/**
	 * 私有方法：发送消息核心逻辑（WebSocket 发送 + 失败入队）
	 * @param {Object} msg - 完整消息对象
	 * @returns {Promise<Object>} 发送成功的消息对象 / 错误信息
	 */
	async #send(msg) {
		try {
			// 1. 检查 WebSocket 连接状态（1 表示已连接）
			if (this.ws.readyState === 1) {
				// 发送消息（转换为 JSON 字符串）
				this.ws.send({
					data: JSON.stringify(msg)
				});

			console.log(`消息发送成功（类型：${msg.messageType}）`, msg);
				return msg;
			} else {
				// 3. WebSocket 未连接：消息入队（后续重发）
				console.warn("WebSocket 未连接，消息入队", msg);
				this.#enqueueMessage(msg);
				return {
					...msg,
					status: "queued"
				}; // 标记为“已入队”
			}
		} catch (e) {
			console.error("发送消息失败", e.message);
			this.#enqueueMessage(msg); // 失败也入队
			return {
				status: "error",
				error: e.message
			};
		}
	}

	/**
	 * 私有方法：消息入队（调用 store 保存队列）
	 * @param {Object} msg - 待入队的消息
	 */
	#enqueueMessage(msg) {
		store.commit("msg/SET_messageQueue", msg);
	}

	// ------------------------------ 公开方法：具体消息类型的发送 ------------------------------
	/**
	 * 发送文本消息
	 * @param {Object} toTarget - 接收目标（{ targetType, targetId }）
	 * @param {string} text - 文本内容
	 * @returns {Promise<Object>} 消息对象
	 */
	async sendText(toTarget, text) {
		if (!text.trim()) {
			uni.showToast({
				title: "不能发送空消息",
				icon: "none"
			});
			return Promise.reject(new Error("消息内容为空"));
		}
		// 构建文本消息内容
		const content = {
			text
		};
		// 构建基础消息 + 发送
		const msg = this.#buildBaseMessage(2, toTarget, content);
		return this.#send(msg);
	}

	/**
	 * 发送语音消息
	 * @param {Object} toTarget - 接收目标
	 * @param {Object} voiceData - 语音数据（{ voicePath, duration }）
	 * @returns {Promise<Object>} 消息对象
	 */
	async sendVoice(toTarget, voiceData) {
		if (!voiceData?.voicePath) {
			uni.showToast({
				title: "语音文件路径不存在",
				icon: "none"
			});
			return Promise.reject(new Error("语音数据无效"));
		}
		const content = {
			voicePath: voiceData.voicePath,
			duration: Math.ceil(voiceData.duration)
		};
		const msg = this.#buildBaseMessage(1, toTarget, content);
		return this.#send(msg);
	}

	/**
	 * 发送视频消息
	 * @param {Object} toTarget - 接收目标
	 * @param {object} videoPath -含videoPath,videoPic 视频路径
	 * @param {string} [text=""] - 视频附带文本（可选）
	 * @returns {Promise<Object>} 消息对象
	 */
	async sendVideo(toTarget, videoPath, text = "") {
		console.log("5555555", videoPath);
		if (typeof(videoPath)!=='object' || Object.keys(videoPath).length===0 ) {
			uni.showToast({
				title: "视频文件路径不存在",
				icon: "none"
			});
			return Promise.reject(new Error("视频数据无效"));
		}

		const content = {
			videoPath,
			text
		};
		const msg = this.#buildBaseMessage(6, toTarget, content);
		return this.#send(msg);
	}

	/**
	 * 发送媒体消息（图片等）
	 * @param {Object} toTarget - 接收目标
	 * @param {Object} mediaData - 媒体数据（{ paths: [{ url, fileID }], content: "" }）
	 * @returns {Promise<Object>} 消息对象
	 */
	async sendMedia(toTarget, mediaData) {
		if (!mediaData?.paths?.length) {
			uni.showToast({
				title: "未选择媒体文件",
				icon: "none"
			});
			return Promise.reject(new Error("媒体数据无效"));
		}
		// 格式化媒体路径（提取 url 和 fileId）
		const mediaPath = mediaData.paths.map(item => ({
			url: item.tempFileURL,
			fileId: item.fileID
		}));
		const content = {
			mediaPath,
			text: mediaData.content || ""
		};
		const msg = this.#buildBaseMessage(3, toTarget, content);
		return this.#send(msg);
	}

	/**
	 * 发送商品消息
	 * @param {Object} toTarget - 接收目标
	 * @param {string} productId - 商品 ID
	 * @returns {Promise<Object>} 消息对象
	 */
	async sendProduct(toTarget, productId) {
		if (!productId) {
			uni.showToast({
				title: "商品 ID 不能为空",
				icon: "none"
			});
			return Promise.reject(new Error("商品数据无效"));
		}
		const content = {
			productId
		};
		const msg = this.#buildBaseMessage(4, toTarget, content);
		return this.#send(msg);
	}
	/**
	 * 发送好友申请
	 * @param {Object} toTarget - 接收目标
	 * @param {string } applyMsg -申请附言
	 * @returns {Promise<Object>} 消息对象
	 */
	async sendApplyFriend(toTarget,applyMsg) {
		const content = {
			text:applyMsg||'好友申请'
		};
		const msg = this.#buildBaseMessage(7, toTarget, content);
		return this.#send(msg);
	}
	/**
	 * @param {Object} toTarget 位置分享
	 */
	async sendLocation(toTarget){
         	const content = {
         		text:"位置分享",
			};
         	const msg = this.#buildBaseMessage(8, toTarget, content);
         	return this.#send(msg);	
		
	}
	/**
	 * 
	 */
	async groupInvite(toTarget,groupInfo){
		const content={
			groupInfo:groupInfo
		}
		const msg=this.#buildBaseMessage(9,toTarget,content)
		return this.#send(msg)
		
	}
}